﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using ChordCreator.Model;

namespace ChordCreator.View.StringsFunctionality
{
    class StringedNoteManager
    {
        /// In this case, lists should be the same length
        /// each index is responsible for one note in every list
        /// TODO: Refactor this, very poor arch decision. Maybe wrap to class?
        private List<int> noteStringList_ = new List<int>();
        private List<int> noteFredList_ = new List<int>();
        private List<ScaleNote> noteList_ = new List<ScaleNote>();
        private List<Color> notePenList_ = new List<Color>();
        private List<Point> noteCenterList_ = new List<Point>();
        private Dictionary<int, List<ScaleNote>> lineSpecification_;

        public void AddDrawedNote(int noteString, int fred, ScaleNote note, Color pen, Point center)
        {
            noteStringList_.Add(noteString);
            noteFredList_.Add(fred);
            noteList_.Add(note);
            notePenList_.Add(pen);
            noteCenterList_.Add(center);
        }

        private void RemoveIndexes(int[] indexes)
        {
            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];
                for (int j = 0; j < indexes.Count(); j++ )
                {
                    if (indexes[j] > index)
                        indexes[j]--;
                }
                noteStringList_.RemoveAt(index);
                noteFredList_.RemoveAt(index);
                noteList_.RemoveAt(index);
                notePenList_.RemoveAt(index);
                noteCenterList_.RemoveAt(index);
            }
        }

        public StringedNoteLine GetNextLine(int offset)
        {
            if (lineSpecification_ == null)
            {
                return null;
            }
            if (noteStringList_.Count == 0)
            {
                return null;
            }
            StringedNoteLine result = new StringedNoteLine();
            List<int> indexesToDelete = new List<int>();
            for (int i=1; i<=HardcodeHelper.StringsCount; i++)
            {
                if (lineSpecification_.ContainsKey(i))
                foreach (ScaleNote note in lineSpecification_[i])
                {
                    int index = GetIndexForStringWithGivenNote(GetNoteOffset(note, offset), i, offset);
                    if (index == -1)
                        continue;

                    result.NoteStringList.Add(noteStringList_[index]);
                    result.NoteFredList.Add(noteFredList_[index]);
                    result.NoteList.Add(noteList_[index]);
                    result.NotePenList.Add(notePenList_[index]);
                    result.NoteCenterList.Add(noteCenterList_[index]);
                    indexesToDelete.Add(index);
                }
            }
            RemoveIndexes(indexesToDelete.ToArray());
            return result;

        }

        /// <summary>
        /// Returns offsetted-note threw scale
        /// </summary>
        /// <param name="note"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        private ScaleNote GetNoteOffset(ScaleNote note, int offset)
        {
            return note;
        }

        private int GetIndexForStringWithGivenNote(ScaleNote note, int noteString, int offset)
        {
//            int index = -1;
//            int fred = int.MaxValue;
//            for (int i = 0; i < noteStringList_.Count; i++)
//            {
//                if (noteStringList_[i] == noteString && noteFredList_[i] < fred)
//                {
//                    fred = noteFredList_[i];
//                    index = i;
//                }
//            }
//            if (noteList_[index] == note)
//            {
//                return index; 
//            }
//            return -1;
            int i = 0;
            while (i<noteStringList_.Count && (noteStringList_[i] != noteString || noteList_[i].Note != note.Note))
            {
                i++;
            }
            int makeOffset = 0;
            while (i < noteStringList_.Count && (makeOffset != offset || noteStringList_[i] != noteString))
            {
                if (noteStringList_[i] == noteString)
                {
                    makeOffset++;
                }
                i++;
            }
            if (i<noteStringList_.Count)
            {
                return i;
            }
            return -1;
        }

        private int GetIndexForStringWithMinFred(int noteString)
        {
            int index = -1;
            int fred = int.MaxValue;
            for (int i=0; i<noteStringList_.Count; i++)
            {
                if (noteStringList_[i] == noteString && noteFredList_[i] < fred)
                {
                    fred = noteFredList_[i];
                    index = i;
                }
            }
            return index;
        }

        /// <summary>
        /// Represents data to draw lines of notes on a strings
        /// </summary>
        public class StringedNoteLine
        {
            public List<int> NoteStringList = new List<int>();
            public List<int> NoteFredList = new List<int>();
            public List<ScaleNote> NoteList = new List<ScaleNote>();
            public List<Color> NotePenList = new List<Color>();
            public List<Point> NoteCenterList = new List<Point>();
            /// <summary>
            /// This field used in drawing algorythm
            /// </summary>
            public Color Color { get; set;}
        }

        public void InitializeLineGear(Dictionary<int, List<ScaleNote>> dictionary)
        {
            lineSpecification_ = dictionary;
        }
    }
}
